from datetime import datetime
import re
from typing import Union

from pydantic import BaseModel, Field, field_validator
from typing_extensions import Literal

from forward.utils.tools import ToolsUtil


class UserAuthSchema(BaseModel):
    id: int = Field(..., description="主键")
    user_id: int = Field(0, description="用户ID")
    openid: str = Field(..., description="Openid")
    unionid: str = Field(..., description="Unionid")
    client: int = Field(
        1,
        description="客户端类型: [1=微信小程序, 2=微信公众号, 3=手机H5, 4=电脑PC, 5=苹果APP, 6=安卓APP]",
    )
    created_time: datetime|None = Field(None, description="创建时间")
    updated_time: datetime|None = Field(None, description="更新时间")
    model_config = {
        "alias_generator": ToolsUtil.to_lower_camel,
        "populate_by_name": True,
    }


class UserSchema(BaseModel):
    """
    用户信息表
    """

    id: int = Field(..., description="主键")
    sn: int = Field(0, description="编号")
    avatar: str = Field(..., description="头像")
    real_name: str = Field(..., description="真实姓名")
    nickname: str = Field(..., description="用户昵称")
    username: str = Field(..., description="用户账号")
    password: str = Field(..., description="用户密码")
    mobile: str = Field(..., description="用户电话")
    salt: str = Field(..., description="加密盐巴")
    sex: int = Field(0, description="用户性别: [1=男, 2=女]")
    channel: int = Field(
        0,
        description="注册渠道: [1=微信小程序, 2=微信公众号, 3=手机H5, 4=电脑PC, 5=苹果APP, 6=安卓APP]",
    )
    is_disable: int = Field(0, description="是否禁用: [0=否, 1=是]")
    is_delete: int = Field(0, description="是否删除: [0=否, 1=是]")
    last_login_ip: str = Field(..., description="最后登录IP")
    last_login_time: datetime | None = Field(None, description="最后登录时间")
    model_config = {
        "alias_generator": ToolsUtil.to_lower_camel,
        "populate_by_name": True,
    }


class UserCenterOutSchema(BaseModel):
    """个人中心返回"""

    id: int  # 主键
    sn: int  # 编号
    avatar: str  # 头像
    realName: str = Field(alias="real_name")  # 真实姓名
    nickname: str  # 用户昵称
    username: str  # 用户账号
    mobile: str  # 用户电话


class UserInfoOutSchema(UserCenterOutSchema):
    """个人信息返回"""

    sex: str  # 用户性别
    is_password: Union[bool, None] = Field(None)  # 用户性别
    is_bind_mnp: Union[bool, None] = Field(None)  # 用户性别
    version: Union[str, None] = None  # 版本
    create_time: datetime | None = Field(None)  # 创建时间


class UserEditInSchema(BaseModel):
    """编辑信息参数"""

    field: str  # 字段
    value: str  # 值


class UserChangePwdInSchema(BaseModel):
    """修改密码参数"""

    # password: str = Field(min_length=6, max_length=20,
    #                       regex='^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$')  # 密码,必须是6-20位字母+数字组合
    password: str
    old_password: str = Field(alias="oldPassword")  # 当前密码

    @field_validator("password", mode="before")
    def check_password(cls, value):
        if not re.fullmatch(r"^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$", value):
            raise ValueError("密码必须是6-20位字母+数字组合")
        return value


class UserBindMobileInSchema(BaseModel):
    """绑定手机参数"""

    type: Literal["bind", "change"]
    mobile: str  # 手机号
    code: str  # 验证码

    @field_validator("mobile", mode="before")
    def check_mobile(cls, value):
        if not re.match(r"^[1][3,4,5,6,7,8,9][0-9]{9}$", value):
            raise ValueError("手机号格式不正确")
        return


class UserMnpMobileInSchema(BaseModel):
    """微信手机号参数"""

    code: str  # 验证码
